package com.xuliugen.jwt.demo.conf;

import com.xuliugen.jwt.demo.exception.AuthorizationException;
import com.xuliugen.jwt.demo.exception.RequestBodyValidException;
import com.xuliugen.jwt.demo.exception.UserIsExistedException;
import com.xuliugen.jwt.demo.exception.UserNotExistedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 控制器Controller统一异常处理
 * @author xuliugen
 * @date 2017/12/5
 */
@RestControllerAdvice
public class ControllerExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 处理Http请求中RequestBody校验未通过的异常
     * @param exception 请求体校验失败异常
     * @return 校验失败的字符信息
     */
    @ExceptionHandler(RequestBodyValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handleInvalidRequest(RequestBodyValidException exception) {
        BindingResult bindingResult = (BindingResult) exception.getObject();

        Map<String, String> resultMap = new HashMap<>(bindingResult.getAllErrors().size());
        bindingResult.getAllErrors().forEach(error -> {
            FieldError fieldError = (FieldError) error;
            resultMap.put(fieldError.getField(), error.getDefaultMessage());
            logger.info("校验错误的属性是:{},错误原因是:{}", fieldError.getField(), error.getDefaultMessage());
        });
        return resultMap;
    }

    @ExceptionHandler(UserIsExistedException.class)
    @ResponseStatus(HttpStatus.CONFLICT)
    public Map<String, String> handleExistedRequest(UserIsExistedException exception) {
        return exceptionMapWrapper(exception.getMessage());
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Map<String, String> handleNotExistedRequest(UserNotExistedException exception) {
        return exceptionMapWrapper(exception.getMessage());
    }

    @ExceptionHandler(AuthorizationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Map<String, String> handleNotExistedRequest(AuthorizationException exception) {
        return exceptionMapWrapper(exception.getMessage());
    }

    /**
     * 通用异常信息返回
     * @param message
     * @return
     */
    private Map<String, String> exceptionMapWrapper(String message) {
        Map<String, String> resultMap = new HashMap<>(1);
        resultMap.put("msg", message);
        return resultMap;
    }

}